Java实现单文件上传、文件预览(流的方式)、单文件下载 功能实例详解 |
您所在的位置:网站首页 › java 上传文件 › Java实现单文件上传、文件预览(流的方式)、单文件下载 功能实例详解 |
这篇文章主要介绍了Java中的单文件上传、文件预览(流的方式)、单文件下载功能的实现,在开发中,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 文章目录 1 :MySql数据库:1.1 :sftp_file 数据1.2:sftp_file 表结构执行创建语句 2 :Controller 单文件上传、文件预览(流的方式)、单文件下载(所有的业务我在Controller 处理的、为了方便大家更直观的阅读代码)2.1:单文件上传2.1.1:单文件上传结果2.1.2:文件上传遇到的 The field file exceeds its maximum permitted size of 1048576 bytes.2.1.2.1:解决方案一 (根据spring boot 版本不同在application文件添加不同的配置)2.1.2.2:解决方案二 (在启动类添加如下代码) 2.2:文件预览(流的方式)2.2.1:文件预览结果 2.3:单文件下载2.3.1:单文件下载结果 3 :其它附属代码 Service,ServiceImpl,Mapper,Mapper.xml 代码如下3.1:Service:3.2:ServiceImpl:3.3:Mapper:3.4 :Mapper.xml: 1 :MySql数据库: 1.1 :sftp_file 数据代码如下(示例): import com.jeewechat.wechat.entity.SftpFile; import com.jeewechat.wechat.service.FileService; import io.swagger.annotations.Api; import lombok.extern.log4j.Log4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.math.BigDecimal; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Date; @Api(value = "FileController", tags = {"文件(附件)信息表"}) @Log4j @Controller @RequestMapping("/file") public class FileController { @Autowired private FileService fileService; /** * @param userId 用户ID * @param file 文件对象 * @return java.lang.String * @description TODO 单文件上传 * @author WangTianLiang * @date 2021/5/19 */ @ApiOperation("单文件上传") @RequestMapping(value = "uploadFile", method = RequestMethod.POST) @ResponseBody public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("userId") String userId) { //step 1: 封装实例对象 SftpFile sftpFile = new SftpFile(); String fileId = SftpFile.createDbId();//随机生产主键ID sftpFile.setFileId(fileId);//文件id sftpFile.setUserId(userId);//操作用户id sftpFile.setCreateTime(new Date());//创建时间 // 获取原始名字 String fileNameUp = file.getOriginalFilename(); sftpFile.setFileNameUp(fileNameUp);//上传文件名称 sftpFile.setFileName(fileId);//存储文件的名称 // 获取后缀名 String suffixType = fileNameUp.substring(fileNameUp.lastIndexOf(".") + 1); sftpFile.setFileType(suffixType);//文件类型 //获得文件大小 Float size = Float.parseFloat(String.valueOf(file.getSize())) / 1024; BigDecimal b = new BigDecimal(size); size = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue(); sftpFile.setFileSize(size.toString());//文件大小(字节单位) // 文件保存路径 String filePath = "E://image//"; sftpFile.setFilePath(filePath);//文件上传路径 // 文件重命名,防止重复 String filePathName = filePath + fileId + "." + sftpFile.getFileType(); //本机ip 静态方法获取InetAddress对象。 InetAddress ia = null; try { ia = ia.getLocalHost();// 获取本地主机 sftpFile.setServerIp(ia.getHostAddress()); } catch (UnknownHostException e) { log.error("文件传输服务器失败:", e); } //step 2: 创建文件对象 File dest = new File(filePathName); //step 3: 判断路径是否存在,如果不存在则创建 if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); } //文件存在,返回 if (dest.exists()) { return "文件已存在"; } try { //step 4: 保存到服务器中 file.transferTo(dest); int i = fileService.insertFile(sftpFile); //step 5: 判断文件对象不为空 if (i > 0) { return "文件上传成功:"+fileId; } } catch (Exception e) { log.error("文件传输服务器失败:", e); } return "文件上传失败"; } } 2.1.1:单文件上传结果SpringBoot文件上传时出现了The field file exceeds its maximum permitted size of 1048576 bytes.错误,显示文件的大小超出了允许的范围。查看了官方文档,原来Spring Boot工程嵌入的tomcat限制了请求的文件大小。 原因:每个文件的配置最大为1Mb,单次请求的文件的总数不能大于10Mb。要更改这个默认值需要在配置文件(如application.properties)中加入两个配置 2.1.2.1:解决方案一 (根据spring boot 版本不同在application文件添加不同的配置) #Spring Boot 1.3.x或者之前 #设置单个文件的大小 multipart.maxFileSize=10Mb #设置单次请求的文件的总大小 multipart.maxRequestSize=1000Mb #Spring Boot 1.4.x #设置单个文件的大小 spring.http.multipart.maxFileSize=10Mb #设置单次请求的文件的总大小 spring.http.multipart.maxRequestSize=1000Mb #Spring Boot 2.0之后 #设置单个文件的大小 spring.servlet.multipart.max-file-size=10Mb #设置单次请求的文件的总大小 spring.servlet.multipart.max-request-size=1000Mb我在项目中采用配置的是Spring Boot 2.0之后(示图): 我在项目中运用(示例): 代码如下(示例): import com.jeewechat.wechat.entity.SftpFile; import com.jeewechat.wechat.service.FileService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; import java.io.RandomAccessFile; @Api(value = "FileController", tags = {"文件(附件)信息表"}) @Log4j @Controller @RequestMapping("/file") public class FileController { @Autowired private FileService fileService; /** * @param fileId 文件ID * @param response * @param request * @return void 返回文件数据 * @description TODO 流的方式预览文件 * @author WangTianLiang * @date 2021/5/18 */ @ApiOperation("文件预览") @ApiImplicitParams({@ApiImplicitParam(name = "fileId", value = "文件对应id", required = true, dataType = "String")}) //@CrossOrigin(origins = "*", maxAge = 3600)//解决跨域问题 origins:是允许访问的列表(origins=“网址”) maxAge:准备响应前的 缓存持续的 最大时间 @RequestMapping(value = "viewFile", method = RequestMethod.GET) public void viewFile(@RequestParam("fileId") String fileId, HttpServletResponse response, HttpServletRequest request) throws Exception { //step 1: 根据 fileId(文件ID)查询 文件详情信息 SftpFile sftpFile = fileService.selectByPrimaryKey(fileId); if (sftpFile == null) { return; } String filePath = sftpFile.getFilePath();//文件上传路径 例如:E:\image String fileName = sftpFile.getFileName();//上传文件名称 例如:学习资料 String fileType = sftpFile.getFileType();//文件类型 例如:docx StringBuffer stringBuffer = new StringBuffer(); //创建StringBuffer 用于拼接文件路径 E://image//学习资料.docx StringBuffer appendFilePath = stringBuffer.append(filePath).append("//").append(fileName).append(".").append(fileType); //step 2: 文件地址,真实环境是存放在数据库中的 File file = new File(appendFilePath.toString()); //step 3: 创建输入对象 FileInputStream fis = new FileInputStream(file); //输出字符流数据或者二进制的字节流数据 OutputStream os = response.getOutputStream(); //step 4: 判断校验文件格式,并设置相关文件格式 if ("jpg,jepg,gif,png,bmp".contains(fileType)) {//图片类型 response.setContentType("image/" + fileType);//设置文件类型参数 } //设置视频 if ("mp4".contains(fileType)) { //开始视频预览 RandomAccessFile targetFile = new RandomAccessFile(file, "r"); //获取从那个字节开始读取文件 String rangeString = request.getHeader("Range"); rangeString = "bytes=0-0"; long fileLength = targetFile.length(); //播放 if (rangeString != null) { long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-"))); //设置内容类型 response.setHeader("Content-Type", "video/" + fileType); //设置此次相应返回的数据长度 response.setHeader("Content-Length", String.valueOf(fileLength - range)); //设置此次相应返回的数据范围 response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength); //返回码需要为206,而不是200 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); //设定文件读取开始位置(以字节为单位) targetFile.seek(range); } } // 创建字节数组 byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { os.write(buf, 0, len); } //关闭流 fis.close(); os.close(); } } 2.2.1:文件预览结果注:文件预览不支持 docx(文档格式),docx 格式预览需要转成 pdf,图片文件、视频文件都支持预览。 代码如下(示例): import com.jeewechat.wechat.entity.SftpFile; import com.jeewechat.wechat.service.FileService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import lombok.extern.log4j.Log4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; @Api(value = "FileController", tags = {"文件(附件)信息表"}) @Log4j @Controller @RequestMapping("/file") public class FileController { @Autowired private FileService fileService; /** * @param fileId * @param response * @return void * @description TODO 单文件下载 * @author WangTianLiang * @date 2021/5/20 */ @ApiOperation("单文件下载") @RequestMapping(value = "downloadFile", method = RequestMethod.GET) @ApiImplicitParams({@ApiImplicitParam(name = "fileId", value = "文件对应id", required = true, dataType = "String")}) public void downloadFile(@RequestParam("fileId") String fileId, HttpServletResponse response) throws Exception { //step 1: 根据 fileId(文件ID)查询 文件详情信息 SftpFile sftpFile = fileService.selectByPrimaryKey(fileId); if (sftpFile == null) { return; } //创建StringBuilder用于拼接文件路径 StringBuilder stringBuilder = new StringBuilder(); //step 2: 获得文件真实路径 StringBuilder filePath = stringBuilder.append(sftpFile.getFilePath()).append(sftpFile.getFileName()).append(".").append(sftpFile.getFileType()); //step 3: 文件地址,真实环境是存放在数据库中的 File file = new File(filePath.toString()); //step 4: 创建输入对象 FileInputStream fis = new FileInputStream(file); //step 5: 设置相关格式 response.setContentType("application/force-download"); // 设置下载后的文件名以及header response.addHeader("Content-disposition", "attachment;fileName=" + java.net.URLEncoder.encode(sftpFile.getFileNameUp(), "UTF-8")); // 创建输出对象 OutputStream os = response.getOutputStream(); // 创建字节数组 byte[] buf = new byte[1024]; int len = 0; while ((len = fis.read(buf)) != -1) { os.write(buf, 0, len); } //关闭流 fis.close(); } } 2.3.1:单文件下载结果项目大致结构如下(如图示例): 代码如下(示例): package com.jeewechat.wechat.service; import com.jeewechat.wechat.entity.SftpFile; public interface FileService { SftpFile selectByPrimaryKey(String fileId); int insertFile(SftpFile sftpFile); } 3.2:ServiceImpl:代码如下(示例): package com.jeewechat.wechat.service.impl; import com.jeewechat.wechat.entity.SftpFile; import com.jeewechat.wechat.mapper.FileMapper; import com.jeewechat.wechat.service.FileService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Slf4j @Service public class FileServiceImpl implements FileService { @Autowired private FileMapper fileMapper; @Override public SftpFile selectByPrimaryKey(String fileId) { return fileMapper.selectByPrimaryKey(fileId); } @Override public int insertFile(SftpFile sftpFile) { return fileMapper.insertFile(sftpFile); } } 3.3:Mapper:代码如下(示例): package com.jeewechat.wechat.mapper; import com.jeewechat.wechat.entity.SftpFile; import org.apache.ibatis.annotations.Mapper; @Mapper public interface FileMapper { int insertFile(SftpFile sftpFile); SftpFile selectByPrimaryKey(String fileId); } 3.4 :Mapper.xml:代码如下(示例): insert into sftp_file file_id, file_name_up, file_name, file_type, file_size, server_ip, file_path, user_id, create_time, #{fileId,jdbcType=VARCHAR}, #{fileNameUp,jdbcType=VARCHAR}, #{fileName,jdbcType=VARCHAR}, #{fileType,jdbcType=VARCHAR}, #{fileSize,jdbcType=VARCHAR}, #{serverIp,jdbcType=VARCHAR}, #{filePath,jdbcType=VARCHAR}, #{userId,jdbcType=DECIMAL}, NOW(), select * from sftp_file where file_id = #{fileId,jdbcType=VARCHAR}希望可以帮助到您… |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |